#include "stdafx.h"
#include "FSHelper.h"

#include <cassert>

CFSHelper::CFSHelper()
{
    m_pFileSystem = NULL;
}

CFSHelper::~CFSHelper()
{
    assert(m_pFileSystem == NULL);
    UnInit();
}

CFSHelper& CFSHelper::GetFSHelper()
{
    static CFSHelper _instance;
    return _instance;
}

BOOL CFSHelper::Init()
{
    CoInitializeEx(0, COINIT_APARTMENTTHREADED);
    if(m_pFileSystem == NULL)
    {
        try
        {
            m_pFileSystem.CreateInstance(__uuidof(FileSystemObject));
        }
        catch (_com_error& e)
        {
            e;
            m_pFileSystem = NULL;
        }
    }
    return (m_pFileSystem != NULL);
}

void CFSHelper::UnInit()
{
    if(m_pFileSystem != NULL)
    {
        m_pFileSystem = NULL;
    }
    CoUninitialize();
}

ULONGLONG CFSHelper::GetFileSize(LPCTSTR szFilePath)
{
    ULONGLONG ulResult = 0L;

    if(!Init())
    {
        return ulResult;
    }

    assert(m_pFileSystem != NULL);
    if(m_pFileSystem != NULL)
    {
        try
        {
            IFilePtr pFile = m_pFileSystem->GetFile(_bstr_t(szFilePath));
            if(pFile != NULL)
            {
                _variant_t varSize = pFile->Size;
                if(varSize.vt != VT_NULL)
                {
                    varSize.ChangeType(VT_UI8, NULL);
                    ulResult = varSize.ullVal;
                }
                pFile = NULL;
            }
        }
        catch (_com_error& e)
        {
            e;
            ulResult = 0L;
        }
    }
    return ulResult;
}

ULONGLONG CFSHelper::GetFolderSize(LPCTSTR szFolderPath)
{
    ULONGLONG ulResult = 0L;

    if(PathIsRoot(szFolderPath))
    {
        ULARGE_INTEGER FreeBytesAvailableToCaller;
        ULARGE_INTEGER TotalNumberOfBytes;
        ULARGE_INTEGER TotalNumberOfFreeBytes;
        if(GetDiskFreeSpaceEx(szFolderPath, &FreeBytesAvailableToCaller, &TotalNumberOfBytes, &TotalNumberOfFreeBytes))
        {
            return TotalNumberOfBytes.QuadPart;
        }

    }

    if(!Init())
    {
        return ulResult;
    }

    assert(m_pFileSystem != NULL);
    if(m_pFileSystem != NULL)
    {
        try
        {
            IFolderPtr pFolder = m_pFileSystem->GetFolder(_bstr_t(szFolderPath));
            if(pFolder != NULL)
            {
                _variant_t varSize = pFolder->Size;
                if(varSize.vt != VT_NULL)
                {
                    varSize.ChangeType(VT_UI8, NULL);
                    ulResult = varSize.ullVal;
                }
                pFolder = NULL;
            }
        }
        catch (_com_error& e)
        {
            e;
            ulResult = 0L;
        }
    }
    return ulResult;
}